package com.spzx.cart.listener;



import com.rabbitmq.client.Channel;
import com.spzx.cart.service.CartService;
import com.spzx.common.rabbitmq.cons.SpzxMqCons;
import jakarta.annotation.Resource;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.Map;

@Component
public class SpzxCartMqListener {
    @Resource
    CartService cartService;
    @RabbitListener(bindings = {
        @QueueBinding(
            value = @Queue(value = "spzx.cart.order.submit.queue",durable = "true"),
            exchange = @Exchange(value = SpzxMqCons.ORDER_EXCHANGE , type = ExchangeTypes.TOPIC),
            key = SpzxMqCons.ORDER_SUBMIT_ROUTING_KEY
        )
    })
    public void delCartItem(Channel channel , Message message , Map<String,Object> map){
        try {
            //1、消费使用消息 执行业务
            if(CollectionUtils.isEmpty(map)){
                return;
            }
            Object userId = map.get("userId");
            if(userId==null){
                return;
            }
            cartService.delCheckedCartItems((Long) userId);
            //2、手动ACK： 发送消息给rabbitmq，表示消息已经使用完毕 rabbitmq接收到ack后会删除消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e) {
            try {
                if(!message.getMessageProperties().isRedelivered()){
                    //第一次消费消息时出现异常，尝试让消息归队 重新消费
                    channel.basicNack(message.getMessageProperties().getDeliveryTag() ,
                                      false , true);
                    System.out.println("第一次消费消息异常，让消息回到队列中");
                }else{
                    //如果第二次消费同一个消息失败 可以丢弃消息(如果消息所在的队列绑定了死信队列 消息会进入死信队列)
                    channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
                    System.out.println("第二次消费消息异常，丢弃消息");
                }
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }

        }
    }
}